package domein;

import java.util.List;

import exceptions.*;

/**
 * Deze klasse beheert de communicatie tussen de gebruikersinterface en subcontrollers.
 * Hij stuurt de vragen van de gebruikersinterface door naar de overeenkomstige subcontroller, die deze vraag afhandelt.
 * Hij stuurt het antwoord terug naar gebruikersinterface.
 * @see GebruikerController
 * @see KlantController
 * @see RekeningController
 * @see ArtikelController
 * @author Stijn Vannieuwenhuyse
 * @author Mattias Gees
 * @author Jelle Maes
 */
public class DomeinController {
	
	private GebruikerController gebruikers;
	private KlantController klanten;
	private RekeningController rekeningen;
	private ArtikelController artikels;
	private boolean gekoppeld;

	private static DomeinController domeincontroller;

//CONTSTRUCTOR
	
	private DomeinController(){
		gebruikers = new GebruikerController();
		klanten = new KlantController();
		rekeningen = new RekeningController();
		artikels = new ArtikelController();
	}
	
	public static DomeinController getInstance(){
		if(DomeinController.domeincontroller == null) {
			DomeinController.domeincontroller = new DomeinController();
		}
		return DomeinController.domeincontroller;
	}
	
	public boolean heeftHuidigeRekeningResource(){
		if(this.isHuidigeResourceSet()){
			if(rekeningen.getHuidigeRekening().getResource() == 0){
				return false;
			}
			else{
				return true;
			}
		}
		else{
			return false;
		}
	}
	
	//GEBRUIKERCONTROLLER handelt deze vragen af...
	
	private Gebruiker getHuidigeGebruiker(){
		return gebruikers.getHuidigeGebruiker();
	}
	
	public String getGebruikerNaam(){
		return this.getHuidigeGebruiker().getVoornaam();
	}
	
	public int getGebruikerLevel(){
		return this.getHuidigeGebruiker().getLevel();
	}

	public void aanmelden(String gebruikersnaam, String wachtwoord) throws WrongLoginException, WrongPasswordException, Exception {		
		try{
			gebruikers.aanmelden(gebruikersnaam, wachtwoord);
		}
		catch(WrongLoginException loginError){
			throw loginError;
		}
		catch(WrongPasswordException passwordError){
			throw passwordError;
		}
		catch(Exception e){
			throw e;
		}
	}
	
	
//KLANTCONTROLLER handelt deze vragen af...
	
	public String[][] getKlantenLijst(String s){
		return this.klanten.getKlantenLijst(s);
	}
	public void setHuidigeKlant(int klantnummer) {
		this.klanten.setHuidigeKlant(klantnummer);
	}
	
	public Klant getHuidigeKlant(){
		return this.klanten.getHuidigeKlant();
	}
	
	public int getHuidigeKlantID(){
		return this.getHuidigeKlant().getId();
	}
	
	public String getHuidigeKlantNaam(){
		return this.getHuidigeKlant().getVoornaam() + " " + this.getHuidigeKlant().getNaam();
	}
	
//REKENINGCONTROLLER handelt deze vragen af...
	
	public String[][] getRekeningenLijst(){
		return rekeningen.getRekeningenLijst();
	}

	public void addRekening(){
		this.rekeningen.addRekening(this.getHuidigeKlant());
	}
	
	public void setHuidigeRekening(int rekeningnummer){
		if(rekeningnummer != 0){
			this.rekeningen.setHuidigeRekening(rekeningnummer);
			this.klanten.setHuidigeKlant(this.rekeningen.getHuidigeRekening().getKlant());
		}
		else{
			this.rekeningen.setHuidigeRekening(null);
			this.klanten.setHuidigeKlant(null);
		}
	}

	public Rekening getHuidigeRekening() throws IndexOutOfBoundsException{
		try{
			if (this.rekeningen.getHuidigeRekening() == null) throw new IndexOutOfBoundsException();
			return this.rekeningen.getHuidigeRekening();
		} catch(IndexOutOfBoundsException e){
			throw e;
		}
	}
	
	public boolean isHuidigeRekeningSet(){
		return this.rekeningen.isHuidigeRekeningSet();
	}
	
	public String[][] getDetailLijnen(){	
		return this.rekeningen.getDetailLijnen(this.getHuidigeRekeningID());
	}
	
	public int getHuidigeRekeningID() {
		return this.rekeningen.getHuidigeRekening() != null ? this.rekeningen.getHuidigeRekening().getId(): 0 ;
	}
	
	public String getHuidigeRekeningDatum() {
		try{
			if (this.rekeningen.getHuidigeRekening() == null) throw new IndexOutOfBoundsException();
			return this.rekeningen.getHuidigeRekening().getDatum().toString();
		} catch(IndexOutOfBoundsException e){
			throw e;
		}
	}
	
	public void addRekeningLijn(int artikelId) throws Exception{
		this.rekeningen.addRekeningLijn(artikelId);
	}
	
	public void addRekeningLijn(int artikelId, int aantal) throws Exception{
		this.rekeningen.addRekeningLijn(artikelId, aantal);
	}
	
	public void removeRekeningLijn(int artikelId) throws Exception{
		rekeningen.removeRekeningLijn(artikelId);
	}
	
	public double getTeBetalenBedrag(){
		return rekeningen.getTeBetalenBedrag();	
	}
	
	public void rekenAf(){
		rekeningen.setRekeningBetaald();
		List<Rekeninglijn> extraLijst = rekeningen.getExtraRekeningLijnen();
		int n = extraLijst.size();
		for(int i = 0;i<n;i++){
			artikels.updateVoorraadExtra(extraLijst.get(i).getArtikel().getId(), extraLijst.get(i).getAantal());
		}
	}
	
	public String[][] getExtraLijnen(){
		return rekeningen.getExtraLijnen();
	}
	
	@SuppressWarnings("static-access")
	public void wijsResourceToe(int aantal){
			try{
				this.addRekeningLijn(this.getHuidigeResourceId(), aantal);
				this.artikels.setResourceBezet(this.getHuidigeRekening());
				Thread.currentThread().sleep(500);
				this.setHuidigeResource(this.getHuidigeResourceId());
				this.setHuidigeRekening(this.getHuidigeRekeningID());
			}catch (Exception e){
			}
	}
	
	@SuppressWarnings("static-access")
	public void geefResourceVrij(){
		this.artikels.setResourceVrij();
		try {
			Thread.currentThread().sleep(500);
		} catch (InterruptedException e) {
		}
		this.setHuidigeResource();
		this.setHuidigeRekening(this.getHuidigeRekeningID());
	}
	
	public double dagopbrengst(){
		return this.rekeningen.dagopbrengst();
	}
	
	public double dagverlies(){
		return this.rekeningen.dagverlies();
	}
//ARTIKELCONTROLLER handelt deze vragen af...	
	
	public void setHuidigeResource(int id) {
		this.artikels.setHuidigeResource(id);
	}
	
	public void setHuidigeResource() {
		this.artikels.setHuidigeResource();
	}
	
	public String[][] getResources() {
		return artikels.getResources();
	}
	
	public String[][] getConsumpties(){
		return artikels.getConsumpties();
	}
	
	public String[][] getExtras(){
		return artikels.getExtras();
	}


	public int getHuidigeResourceId(){
		return artikels.getHuidigeResourceId();
	}

	public boolean isHuidigeResourceSet() {
		return artikels.isHuidigeResourceSet();
	}

	public boolean isHuidigeResourceBezet() {
		return artikels.isHuidigeResourceBezet();
	}
	
	public void updateVoorraadExtra(int id){
		this.artikels.updateVoorraadExtra(id);
	}

	public boolean isGekoppeld(){
		return this.gekoppeld;
	}
	
	public void setGekoppeld(boolean gekoppeld){
		this.gekoppeld = gekoppeld;
	}
	public boolean zijnResourcesVrij(){
		return this.artikels.zijnResourcesVrij();
	}
}